package com.tomorrowbbs.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;

import com.tomorrowbbs.domain.UserIntegralRecord;
import com.tomorrowbbs.domain.UserMessage;
import com.tomorrowbbs.domain.config.WebConfig;
import com.tomorrowbbs.domain.constants.Constants;
import com.tomorrowbbs.domain.dto.SessionWebUserDto;
import com.tomorrowbbs.domain.enums.*;
import com.tomorrowbbs.exception.BusinessException;
import com.tomorrowbbs.utils.JsonUtils;
import com.tomorrowbbs.utils.OKHttoUtils;
import com.tomorrowbbs.utils.StringTools;
import com.tomorrowbbs.utils.SysCacheUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.tomorrowbbs.mapper.UserInfoMapper;
import com.tomorrowbbs.domain.UserInfo;
import com.tomorrowbbs.service.IUserInfoService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 用户信息Service业务层处理
 * 
 * @author zjz
 * @date 2024-11-09
 */
@Service
public class UserInfoServiceImpl implements IUserInfoService
{

    private static final Logger logger = LoggerFactory.getLogger(UserInfoServiceImpl.class);
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private EmailCodeServiceImpl emailCodeService;
    @Autowired
    private UserMessageServiceImpl userMessageService;
    @Autowired
    private UserIntegralRecordServiceImpl userIntegralRecordService;
    @Autowired
    private WebConfig webConfig;

    /**
     * 查询用户信息
     * 
     * @param userId 用户信息主键
     * @return 用户信息
     */
    @Override
    public UserInfo selectUserInfoByUserId(String userId)
    {
        return userInfoMapper.selectUserInfoByUserId(userId);
    }

    /**
     * 查询用户信息列表
     * 
     * @param userInfo 用户信息
     * @return 用户信息
     */
    @Override
    public List<UserInfo> selectUserInfoList(UserInfo userInfo)
    {
        return userInfoMapper.selectUserInfoList(userInfo);
    }

    /**
     * 新增用户信息
     * 
     * @param userInfo 用户信息
     * @return 结果
     */
    @Override
    public int insertUserInfo(UserInfo userInfo)
    {
        return userInfoMapper.insertUserInfo(userInfo);
    }

    /**
     * 修改用户信息
     * 
     * @param userInfo 用户信息
     * @return 结果
     */
    @Override
    public int updateUserInfo(UserInfo userInfo)
    {
        return userInfoMapper.updateUserInfo(userInfo);
    }

    /**
     * 批量删除用户信息
     * 
     * @param userIds 需要删除的用户信息主键
     * @return 结果
     */
    @Override
    public int deleteUserInfoByUserIds(String[] userIds)
    {
        return userInfoMapper.deleteUserInfoByUserIds(userIds);
    }

    /**
     * 删除用户信息信息
     * 
     * @param userId 用户信息主键
     * @return 结果
     */
    @Override
    public int deleteUserInfoByUserId(String userId)
    {
        return userInfoMapper.deleteUserInfoByUserId(userId);
    }

    /**
     * 登录注册
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void register(String email, String emailCode, String nickName, String password) {
        //判断邮箱是否存在
        UserInfo userInfo = userInfoMapper.selectUserInfoByEmail(email);
        if (userInfo != null){
            throw new BusinessException("邮箱账号已存在");
        }
        //判断昵称是否存在
        userInfo = userInfoMapper.selectUserByNickName(nickName);
        if (userInfo != null){
            throw new BusinessException("昵称已存在");
        }
        emailCodeService.checkCode(email, emailCode);

        String userId = StringTools.getRandomNumber(Constants.LENGTH_10);

        UserInfo insertInfo = new UserInfo();
        insertInfo.setUserId(userId);
        insertInfo.setEmail(email);
        insertInfo.setNickName(nickName);
        insertInfo.setPassword(StringTools.encodeMd5(password));
        insertInfo.setJoinTime(new Date());
        insertInfo.setStatus(UserStatusEnum.ENABLE.getStatus());
        insertInfo.setTotalIntegral(0l);
        insertInfo.setCurrentIntegral(0l);

        userInfoMapper.insertUserInfo(insertInfo);

        //更新积分
        updateUserIntegral(userId, UserIntegralOperTypeEnum.REGISTER, UserIntegralChangeTypeEnum.ADD.getChangeType(), Constants.Integral_5);

        //记录消息
        UserMessage userMessage = new UserMessage();
        userMessage.setReceivedUserId(userId);
        userMessage.setMessageType(MessageTypeEnum.SYS.getType());
        userMessage.setCreateTime(new Date());
        userMessage.setStatus(MessageStatusEnum.NO_READ.getStatus());
        userMessage.setMessageContent(SysCacheUtils.getSysSetting().getRegisterSetting().getRegisterWelcomeInfo());
        userMessageService.insertUserMessage(userMessage);
    }

    /**
     * 更新用户积分
     */
    public void updateUserIntegral(String userId, UserIntegralOperTypeEnum operTypeEnum, Integer changeType, Long integral) {
        integral = integral * changeType;
        if(integral == 0){
            return;
        }
        UserInfo userInfo = userInfoMapper.selectUserInfoByUserId(userId);
        if (UserIntegralChangeTypeEnum.REDUCE.getChangeType().equals(changeType) && userInfo.getCurrentIntegral() + integral < 0){
            integral = changeType * userInfo.getCurrentIntegral();
        }
        UserIntegralRecord record = new UserIntegralRecord();
        record.setUserId(userId);
        record.setOperType(operTypeEnum.getOperType());
        record.setCreateTime(new Date());
        record.setIntegral(integral);
        userIntegralRecordService.insertUserIntegralRecord(record);

        Integer count = userInfoMapper.updateIntegral(userId, integral);
        if (count == 0){
            throw new BusinessException("更新用户积分失败");
        }
    }

    /**
     * 登录
     * @param email
     * @param password
     * @param ip
     * @return
     */
    @Override
    public SessionWebUserDto login(String email, String password, String ip) {
        UserInfo userInfo = userInfoMapper.selectUserInfoByEmail(email);
        System.out.println("userInfo: "+ userInfo);
        if(userInfo == null || !userInfo.getPassword().equals(password)){
            throw new BusinessException("账号或密码错误");
        }
        if (UserStatusEnum.DISABLE.getStatus().equals(userInfo.getStatus())){
            throw new BusinessException("账号已被禁用");
        }

        String ipAddress = getIpAddress(ip);

        UserInfo updateInfo = new UserInfo();
        updateInfo.setUserId(userInfo.getUserId());
        updateInfo.setLastLoginTime(new Date());
        updateInfo.setLastLoginIp(ip);
        updateInfo.setLastLoginIpAddress(ipAddress);
        userInfoMapper.updateUserInfo(updateInfo);

        SessionWebUserDto sessionWebUserDto=new SessionWebUserDto();
        sessionWebUserDto.setNickName(userInfo.getNickName());
        sessionWebUserDto.setProvince(ipAddress);
        sessionWebUserDto.setUserId(userInfo.getUserId());
        if(!StringTools.isEmpty(webConfig.getAdminEmails()) && ArrayUtils.contains(webConfig.getAdminEmails().split(","),userInfo.getEmail())){
            sessionWebUserDto.setIsAdmin(true);
        }else {
            sessionWebUserDto.setIsAdmin(false);
        }
        return sessionWebUserDto;
    }


    /**
     * 获取IP地址
     * @param ip
     * @return
     */
    public String getIpAddress(String ip){
        try {
            String Url = "http://whois.pconline.com.cn/ipJson.jsp?json=true&ip="+ip;
            String responseJson = OKHttoUtils.getRequest(Url);
            if (responseJson==null){
                return Constants.NO_ADDRESS;
            }
            Map<String,String> addressInfo = JsonUtils.convertJson2Obj(responseJson, Map.class);
            return addressInfo.get("pro");
        }catch (Exception e){
            logger.error("获取IP地址信息失败",e);
        }
        return Constants.NO_ADDRESS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resetPwd(String email, String password, String emailCode) {
        UserInfo userInfo = userInfoMapper.selectUserInfoByEmail(email);
        if (userInfo == null){
            throw new BusinessException("邮箱不存在");
        }
        emailCodeService.checkCode(email, emailCode);
        UserInfo updateInfo = new UserInfo();
        updateInfo.setUserId(userInfo.getUserId());
        updateInfo.setPassword(StringTools.encodeMd5(password));
        userInfoMapper.updateUserInfo(updateInfo);
    }
}














